home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / ab20 / unarced / utilities / system / intuition / shadow / examples / test / performancetests.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-03-17  |  27.8 KB  |  1,047 lines

  1. /*
  2.  * These used to be compile-time options to Browser.
  3.  *
  4.  * Obviously this makes no sense for public code, so I have
  5.  *  stuck all of that here.
  6.  *
  7.  * Makes Browser less unintelligble :^/
  8.  *
  9.  * (C) Copyright 1991 David C. Navas
  10.  */
  11. #include <shadow/coreMeta.h>
  12. #include <shadow/coreRoot.h>
  13. #include <shadow/process.h>
  14. #include <shadow/semaphore.h>
  15.  
  16. #include <ipc.h>
  17. #include <shadow/shadow_proto.h>
  18. #include <shadow/shadow_pragmas.h>
  19. #include <shadow/method.h>
  20. #include <dos/dostags.h>
  21. #include <proto/dos.h>
  22. #include <proto/exec.h>
  23. #include <math.h>
  24.  
  25. extern struct ExecBase * __far SysBase;
  26. struct IPCBase * __far IPCBase;
  27. struct ShadowBase * __far ShadowBase;
  28. struct DosLibrary * __far DOSBase;
  29.  
  30. struct SignalSemaphore programSemaphore;
  31.  
  32. /*
  33.  * To test the binary tree speed.
  34.  */
  35. void BinSpeedTest(void);
  36.  
  37. /*
  38.  * To test the memory speed.
  39.  */
  40. void MemorySpeedTest(void);
  41.  
  42. /*
  43.  * To test the semaphore speed.
  44.  */
  45. void SemaphoreSpeedTest(void);
  46.  
  47. /*
  48.  * To test the FindString() speed.
  49.  */
  50. void StringSpeedTest(void);
  51.  
  52. /*
  53.  * This is for the method testing and patching/attribute tests.
  54.  */
  55.  
  56. #define METHOD_TEST_SPEED     "Method Tst5"
  57. extern METHOD_REF REF_TestMethod[],
  58.                   REF_SendTestMethod[],
  59.                   REF_SendTest5Method[];
  60.  
  61. long TestMethod(METHOD_ARGS, char *), SendTestMethod(METHOD_ARGS,
  62.                                                      OBJECT testObject);
  63. long Test5Method(METHOD_ARGS), SendTest5Method(METHOD_ARGS, OBJECT);
  64.  
  65. #define SPEEDTESTNUMBER  100000
  66.  
  67. /*
  68.  * Class that is to be run by "testing subprocess..."
  69.  */
  70.  
  71. /*
  72.  * These methods are called by this test program in main()
  73.  */
  74. METHOD_TAG methods2[] =
  75.                         {
  76.                            {
  77.                               "Method TEST",
  78.                               NULL, NULL,
  79.                               SHADOW_MSG_SYNC,
  80.                               METHOD_FLAG_PROC, 0,
  81.                               (METHODFUNCTYPE)SendTestMethod, REF_SendTestMethod
  82.                            },
  83.                            {
  84.                               METHOD_TEST_SPEED,
  85.                               NULL, NULL,
  86.                               SHADOW_MSG_SYNC,
  87.                               METHOD_FLAG_PROC, 0,
  88.                               (METHODFUNCTYPE)SendTest5Method, REF_SendTest5Method
  89.                            },
  90.                            TAG_END
  91.                         };
  92.  
  93. struct TestDefaultAttribute
  94. {
  95.    long thing;
  96. };
  97.  
  98. ATTRIBUTE_TAG attrs2[] =
  99.                         {
  100.                            {
  101.                               "A default attribute",
  102.                               sizeof(struct TestDefaultAttribute),
  103.                               NULL
  104.                            },
  105.                            TAG_END
  106.                         };
  107.  
  108.  
  109. /*
  110.  * Class that is to be run by the "Fake dos Process..."
  111.  */
  112.  
  113. /*
  114.  * These are the methods that are called in the inner loop by the
  115.  *  methods defined above.
  116.  */
  117. METHOD_TAG methods[] =
  118.                         {
  119.                            {
  120.                               "Method TEST",
  121.                               NULL, NULL,
  122.                               SHADOW_MSG_SYNC,
  123.                               METHOD_FLAG_PROC, 0,
  124.                               (METHODFUNCTYPE)TestMethod, REF_TestMethod
  125.                            },
  126.                            {
  127.                               METHOD_TEST_SPEED,
  128.                               NULL, NULL,
  129.                               SHADOW_MSG_CALL,         /* Edit this one! */
  130.                               METHOD_FLAG_PROC, 0,
  131.                               (METHODFUNCTYPE)Test5Method, NULL
  132.                            },
  133.                            TAG_END
  134.                         };
  135.  
  136. /*
  137.  * The patches
  138.  */
  139. extern double PreTestMethod(METHOD_ARGS);
  140.  
  141. METHOD_TAG preMethod =
  142.                            {
  143.                               "Method TEST",
  144.                               NULL, NULL,
  145.                               SHADOW_MSG_SYNC,
  146.                               METHOD_FLAG_PROC | METHOD_FLAG_CHECK_CONTINUE, 1,
  147.                               (METHODFUNCTYPE)PreTestMethod, NULL
  148.                            };
  149.  
  150. extern long PostTestMethod(METHOD_ARGS);
  151.  
  152. METHOD_TAG postMethod =
  153.                            {
  154.                               "Method TEST",
  155.                               NULL, NULL,
  156.                               SHADOW_MSG_SYNC,
  157.                               METHOD_FLAG_PROC, -1,
  158.                               (METHODFUNCTYPE)PostTestMethod, NULL
  159.                            };
  160.  
  161.  
  162.  
  163. /*
  164.  * A default attribute, just to show you how they work.
  165.  */
  166. struct TestDefaultAttribute theDefAtt = {0xFEED};
  167.  
  168. /*
  169.  * Here, we not only test the default attribute, but we show that you
  170.  * can give a new class a default attribute for an attribute of the new
  171.  * class' superclass.
  172.  */
  173. ATTRIBUTE_TAG attrs[] =
  174.                         {
  175.                            {
  176.                               "A default attribute",
  177.                               sizeof(struct TestDefaultAttribute),
  178.                               &theDefAtt
  179.                            },
  180.                            TAG_END
  181.                         };
  182.  
  183.  
  184. /*
  185.  * Lattice, go away.
  186.  */
  187. int CXBRK(void)
  188. {
  189.    return(0);
  190. }
  191.  
  192. /*
  193.  * really.
  194.  */
  195. chkabort(void)
  196. {
  197.    return(0);
  198. }
  199.  
  200.  
  201. /*
  202.  * Some memory allocation routines.  Dunno why we have these here...
  203.  */
  204. /*
  205. void * __regargs temporaryAlloc(struct MemoryList *list)
  206. {
  207.    return AllocMem(32 * 32 + sizeof(struct MemoryNode), MEMF_PUBLIC);
  208. }
  209.  
  210. void __regargs temporaryFree(struct MemoryList *list,
  211.                            struct MemoryNode *node)
  212. {
  213.    FreeMem(node, 32 * 32 + sizeof(struct MemoryNode));
  214. }
  215. */
  216.  
  217. /*
  218.  * Possible test constants
  219.  */
  220. #define MEMORYTEST   "MEMORY"
  221. #define SPEEDTEST    "METHOD"
  222. #define FEATURETEST  "TEST"
  223. #define AVLTREETEST  "AVL"
  224. #define SEMTEST      "SEMAPHORE"
  225. #define STRINGTEST   "STRING"
  226.  
  227. #define MEMORYTEST_VAL  1
  228. #define SPEEDTEST_VAL   2
  229. #define FEATURETEST_VAL 4
  230. #define AVLTREETEST_VAL 8
  231. #define SEMTEST_VAL     16
  232. #define STRINGTEST_VAL  32
  233.  
  234. void main(int argc, char *argv[])
  235. {
  236.    CLASS root,
  237.          dosTaskClass,
  238.          testClass,
  239.          dosClass,
  240.          proc;
  241.  
  242.    OBJECT procObject,
  243.           testObject,
  244.           dosTask,
  245.           dosObject,
  246.           preObject,
  247.           postObject;
  248.    ULONG args[10], test = 0, i;
  249.  
  250.    InitSemaphore(&programSemaphore);
  251.  
  252.    if (!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 37)))
  253.    {
  254.       DOSBase = (struct DosLibrary *)OpenLibrary("dos.library", 0);
  255.       Write(Output(), "Sorry, use 2.0\n", 15);
  256.       CloseLibrary(DOSBase);
  257.       return;
  258.    }
  259.  
  260.    if (argc == 0)
  261.    {
  262.       VPrintf("Run this from the Shell\n", NULL);
  263.       CloseLibrary(DOSBase);
  264.       return;
  265.    }
  266.  
  267.    if ((argc == 1) || !stricmp(argv[1], "?"))
  268.    {
  269.       VPrintf("\nOkay, this is how you want to run this program:\n\t%s ",
  270.               (ULONG *)&argv[0]);
  271.       VPrintf(MEMORYTEST"/S,"SPEEDTEST"/S,"FEATURETEST"/S,"
  272.               AVLTREETEST"/S,"SEMTEST"/S,"STRINGTEST"/S\n\n", NULL);
  273.       CloseLibrary(DOSBase);
  274.       return;
  275.    }
  276.  
  277.    for(i = 1; i < argc; i++)
  278.    {
  279.       if (!stricmp(argv[i], MEMORYTEST))
  280.          test |= MEMORYTEST_VAL;
  281.       else
  282.          if (!stricmp(argv[i], SPEEDTEST))
  283.             test |= SPEEDTEST_VAL;
  284.       else
  285.          if (!stricmp(argv[i], FEATURETEST))
  286.             test |= FEATURETEST_VAL;
  287.       else
  288.          if (!stricmp(argv[i], AVLTREETEST))
  289.             test |= AVLTREETEST_VAL;
  290.       else
  291.          if (!stricmp(argv[i], SEMTEST))
  292.             test |= SEMTEST_VAL;
  293.       else
  294.          if (!stricmp(argv[i], STRINGTEST))
  295.             test |= STRINGTEST_VAL;
  296.       else
  297.          VPrintf("Disregarding Parameter <%s>\n", (ULONG *)&argv[i]);
  298.    }
  299.  
  300.    if (!(IPCBase = OpenLibrary("ppipc.library", 0)))
  301.    {
  302.       VPrintf("requires ppipc.library in libs:\n", NULL);
  303.       CloseLibrary(DOSBase);
  304.       return;
  305.    }
  306.  
  307.    if (!(ShadowBase = (struct ShadowBase *)
  308.                        OpenLibrary("shadow.library", 4)))
  309.    {
  310.       VPrintf("requires shadow.library 4.3 in libs:\n", NULL);
  311.       CloseLibrary(IPCBase);
  312.       CloseLibrary(DOSBase);
  313.       return;
  314.    }
  315.  
  316.    if (!InitOOProgram("Performance Tester Program"))
  317.    {
  318.       CloseLibrary(IPCBase);
  319.       CloseLibrary(ShadowBase);
  320.       CloseLibrary(DOSBase);
  321.       return;
  322.    }
  323.  
  324.    if (test & AVLTREETEST_VAL)
  325.       BinSpeedTest();
  326.  
  327.    if (test & MEMORYTEST_VAL)
  328.       MemorySpeedTest();
  329.  
  330.    if (test & SEMTEST_VAL)
  331.       SemaphoreSpeedTest();
  332.  
  333.    if (test & STRINGTEST_VAL)
  334.       StringSpeedTest();
  335.  
  336.    /*
  337.     * What follows below is a complete mess.
  338.     * The author realizes it, but doesn't care enough about this
  339.     *  particular stretch of code to do much about it.
  340.     * Please, refer to the other examples provided for better use of
  341.     *  the shadow.lib functions.
  342.     * If you like, think of this as an example of more direct mucking
  343.     *  about with creating classes and objects, without
  344.     *  Create[Instance|SubClass]
  345.     */
  346.    proc = FindJazzClass(PROCESSCLASS);
  347.    root = FindJazzClass(ROOTCLASS);
  348.  
  349.    if (test & (SPEEDTEST_VAL | FEATURETEST_VAL))
  350.    {
  351.       struct Meta *MHClass;
  352.  
  353.       dosTaskClass = DoJazzMethod(proc, NULL, METHOD_META_SUB,
  354.                                               "dos process class",
  355.                                               NULL,
  356.                                               NULL,
  357.                                               NULL,
  358.                                               METHOD_END);
  359.  
  360.       args[0] = (ULONG)proc;
  361.       args[1] = proc->ccl_size;
  362.       args[2] = (ULONG)dosTaskClass;
  363.       VPrintf("Defined procClass:<%lx> : %ld bytes :: dosProcClass:<%lx>\n",
  364.               args);
  365.  
  366.       args[0] = NP_Output;
  367.       args[1] = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
  368.       args[2] = TAG_END;
  369.       dosTask = DoJazzMethod(dosTaskClass, NULL, METHOD_META_CREATE,
  370.                                                  METHOD_END);
  371.       dosTask = DoJazzMethod(dosTask, NULL, METHOD_META_INIT,
  372.                                             "Fake dos Task",
  373.                                             NULL,
  374.                                             &programSemaphore,
  375.                                             args,
  376.                                             METHOD_END);
  377.  
  378.       /*
  379.        * if didn't Open, then free the resources.
  380.        */
  381.       if (args[0] != TAG_IGNORE)
  382.       {
  383.          VPrintf("Couldn't start the Fake dos Task\n", NULL);
  384.          Close(args[1]);
  385.       }
  386.  
  387.       args[0] = NP_Output;
  388.       args[1] = (ULONG)Open("CONSOLE:", MODE_OLDFILE);
  389.       args[2] = TAG_END;
  390.       procObject = DoJazzMethod(proc, NULL, METHOD_META_CREATE, METHOD_END);
  391.       procObject = DoJazzMethod(procObject, NULL, METHOD_META_INIT,
  392.                                                   "testing subprocess...",
  393.                                                   NULL,
  394.                                                   &programSemaphore,
  395.                                                   args,
  396.                                                   METHOD_END);
  397.       /*
  398.        * if didn't Open, then free the resources.
  399.        */
  400.       if (args[0] != TAG_IGNORE)
  401.       {
  402.          VPrintf("Couldn't start the testing subprocess...", NULL);
  403.          Close(args[1]);
  404.       }
  405.  
  406.  
  407.       args[0] = (ULONG)procObject;
  408.       args[1] = (ULONG)dosTask;
  409.       VPrintf("Proc Objects %lx %lx\n\n", args);
  410.  
  411.       SetupMethodTags(methods2, procObject, (void *)-1);
  412.       SetupMethodTags(methods, dosTask, (void *)-1);
  413.  
  414.       testClass = DoJazzMethod(root, NULL, METHOD_META_SUB,
  415.                                                       "Test Class",
  416.                                                       NULL,
  417.                                                       attrs2,
  418.                                                       methods2,
  419.                                                       METHOD_END);
  420.  
  421.       testObject = DoJazzMethod( DoJazzMethod(testClass,
  422.                                               NULL,
  423.                                               METHOD_META_CREATE,
  424.                                               METHOD_END),
  425.                                  NULL,
  426.                                  METHOD_META_INIT,
  427.                                  METHOD_END);
  428.  
  429.       dosClass = DoJazzMethod(testClass, NULL, METHOD_META_SUB,
  430.                                                         "Test Class Dest",
  431.                                                         NULL,
  432.                                                         attrs,
  433.                                                         methods,
  434.                                                         METHOD_END);
  435.  
  436.       dosObject = DoJazzMethod(dosClass, NULL, METHOD_META_CREATE, METHOD_END);
  437.  
  438.       if (test & FEATURETEST_VAL)
  439.       {
  440.          /*
  441.           * Well, did the attribute turn out okay?
  442.           */
  443.          VPrintf("Default Attribute Value :: %lx\n\n",
  444.                  FindAttribute(dosObject, "A default attribute"));
  445.  
  446.       }
  447.       dosObject = DoJazzMethod(dosObject, NULL, METHOD_META_INIT, METHOD_END);
  448.  
  449.  
  450.       AddAutoResource(NULL, testClass, NULL);
  451.       AddAutoResource(NULL, dosTaskClass, NULL);
  452.       AddAutoResource(NULL, UseObject(dosObject), NULL);
  453.       AddAutoResource(NULL, UseObject(dosClass), NULL);
  454.       AddAutoResource(NULL, UseObject(testObject), NULL);
  455.       AddAutoResource(NULL, procObject, NULL);
  456.       AddAutoResource(NULL, UseObject(dosTask), NULL);
  457.  
  458.       if (test & FEATURETEST_VAL)
  459.       {
  460.          MHClass = FindJazzClass(PATCHERCLASS);
  461.  
  462.          /*
  463.           * Add pre and post patches
  464.           */
  465.          preMethod.mtag_procObject = dosTask;
  466.          preMethod.mtag_defnObject = (OBJECT)FindTask(NULL)->tc_UserData;
  467.  
  468.          preObject = DoJazzMethod(MHClass, NULL, METHOD_META_CREATE,
  469.                                                  METHOD_END);
  470.          preObject = DoJazzMethod(preObject, NULL, METHOD_META_INIT,
  471.                                                    &preMethod,
  472.                                                    dosClass,
  473.                                                    METHOD_END);
  474.          VPrintf("Added prePatch %lx\n", (ULONG *)&preObject);
  475.  
  476.          postMethod.mtag_procObject = dosTask;
  477.          postMethod.mtag_defnObject = (OBJECT)FindTask(NULL)->tc_UserData;
  478.  
  479.          postObject = DoJazzMethod(MHClass, NULL, METHOD_META_CREATE,
  480.                                                   METHOD_END);
  481.          postObject = DoJazzMethod(postObject, NULL, METHOD_META_INIT,
  482.                                                      &postMethod,
  483.                                                      dosClass,
  484.                                                      METHOD_END);
  485.          VPrintf("Added postPatch %lx\n", (ULONG *)&postObject);
  486.  
  487.          DropObject(MHClass);
  488.  
  489.          /*
  490.           * Method patching tests.
  491.           */
  492.          VPrintf("\nMETHOD TESTING\n", NULL);
  493.          DoJazzMethod(testObject, NULL, "Method TEST", dosObject,
  494.                                                        METHOD_END);
  495.          DoJazzMethod(preObject, NULL, METHOD_META_REMOVE, METHOD_END);
  496.          DropObject(preObject);
  497.          VPrintf("Removed prePatch\n\n", NULL);
  498.  
  499.          DoJazzMethod(testObject, NULL, "Method TEST", dosObject,
  500.                                                        METHOD_END);
  501.  
  502.          DoJazzMethod(postObject, NULL, METHOD_META_REMOVE, METHOD_END);
  503.          DropObject(postObject);
  504.          VPrintf("Removed postPatch\n\n", NULL);
  505.  
  506.          DoJazzMethod(testObject, NULL, "Method TEST", dosObject,
  507.                                                       METHOD_END);
  508.          VPrintf("METHOD TESTING DONE\n\n", NULL);
  509.       }
  510.  
  511.       if (test & SPEEDTEST_VAL)
  512.       {
  513.          /*
  514.           * A3000 tests under moderate system usage (maky apps Open, nothing
  515.           *  running) shows 31000+ for methods/sec, and 240000 for funcs/sec.
  516.           */
  517.          DoJazzMethod(testObject, NULL, METHOD_TEST_SPEED, dosObject,
  518.                                                            METHOD_END);
  519.       }
  520.  
  521.       DropObject(dosObject);
  522.       DropObject(dosClass);
  523.       DropObject(testObject);
  524.       DropObject(dosTask);
  525.    }
  526.    DropObject(root);
  527.    DropObject(proc);
  528.  
  529.    VPrintf("Removing current program\n", NULL);
  530.  
  531.    RemoveCurrentProgram(&programSemaphore);
  532.  
  533.    VPrintf("Closing libraries\n", NULL);
  534.  
  535.    CloseLibrary(ShadowBase);
  536.    CloseLibrary(IPCBase);
  537.  
  538.    VPrintf("Attempting to purge SHADOW and PPIPC libraries.\n", NULL);
  539.    CloseLibrary(DOSBase);
  540.  
  541.    /*
  542.     * Purge everything.
  543.     */
  544.  
  545.    AllocMem(-1, MEMF_ANY);
  546. }
  547.  
  548. void BinSpeedTest(void)
  549. {
  550.    AVLTREE bt = NULL;
  551.    int i, j;
  552.    struct DateStamp ds1, ds2;
  553.    struct ClasslessObject object[256];
  554.  
  555.    for(i = 0;i < 256; i++)
  556.    {
  557.       object[i].clb_class = NULL;
  558.       object[i].clb_useCount = object[i].clb_size = 0;
  559.    }
  560.  
  561.  
  562.    for (i = 0; i < 256; i++)
  563.    {
  564.       AddNodeBinTree(&bt, &object[i], i);
  565.    }
  566.  
  567.    VPrintf("Beginning SHADOW AVLTree speed test of FindBinNode:\n", NULL);
  568.  
  569.    DateStamp((void *)&ds1);
  570.    for(j = 0; j < 100; j++)
  571.    {
  572.       for (i = 0; i < 256; i++)
  573.       {
  574.          DropObject(FindBinNode(&bt, i));
  575.       }
  576.  
  577.    }
  578.    DateStamp((void *)&ds2);
  579.  
  580.    for (i = 0; i < 256; i++)
  581.    {
  582.       RemoveBinNode(&bt, &object[i], i);
  583.    }
  584.  
  585.    ds2.ds_Tick -= ds1.ds_Tick;
  586.    ds2.ds_Minute -= ds1.ds_Minute;
  587.    if (ds2.ds_Tick < 0)
  588.    {
  589.       --ds2.ds_Minute;
  590.       ds2.ds_Tick += (60 * 50);
  591.    }
  592.    ds2.ds_Days = ds2.ds_Minute;
  593.    ds2.ds_Minute = ds2.ds_Tick / 50;
  594.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  595.  
  596.    VPrintf("SHADOW AVLTree speed test completed.\n", NULL);
  597.    i = 50 * 25600;
  598.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  599.    VPrintf("\t%ld SHADOW AVLTree FindBinNode()/second\n\n", &i);
  600.  
  601.  
  602.    VPrintf("Beginning SHADOW AVLTree speed test Add/Remove:\n", NULL);
  603.  
  604.    DateStamp((void *)&ds1);
  605.    for(j = 0; j < 50; j++)
  606.    {
  607.       for (i = 0; i < 256; i++)
  608.       {
  609.          AddNodeBinTree(&bt, &object[i], i);
  610.       }
  611.       for (i = 0; i < 256; i++)
  612.       {
  613.          RemoveBinNode(&bt, &object[i], i);
  614.       }
  615.  
  616.    }
  617.    DateStamp((void *)&ds2);
  618.    ds2.ds_Tick -= ds1.ds_Tick;
  619.    ds2.ds_Minute -= ds1.ds_Minute;
  620.    if (ds2.ds_Tick < 0)
  621.    {
  622.       --ds2.ds_Minute;
  623.       ds2.ds_Tick += (60 * 50);
  624.    }
  625.    ds2.ds_Days = ds2.ds_Minute;
  626.    ds2.ds_Minute = ds2.ds_Tick / 50;
  627.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  628.  
  629.    VPrintf("SHADOW AVLTree speed test completed.\n", NULL);
  630.    i = 50 * 12800;
  631.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  632.    VPrintf("\t%ld SHADOW AVLTree Adds-Removes/second\n\n", &i);
  633.  
  634. }
  635.  
  636. void MemorySpeedTest(void)
  637. {
  638.    int i, j;
  639.    void *table[128];
  640.    struct DateStamp ds1, ds2;
  641.    struct MemoryList globalMemList;
  642.  
  643.    VPrintf("Beginning SHADOW memory allocation speed test:\n", NULL);
  644.  
  645.    InitTable(&globalMemList, NULL, NULL, 16);
  646.  
  647.    DateStamp((void *)&ds1);
  648.  
  649.    for(j = 0; j < 500; j++)
  650.    {
  651.       for (i = 0; i < 128; i++)
  652.       {
  653.          table[i] = AllocateItem(&globalMemList);
  654.       }
  655.       for (i = 0; i < 128; i++)
  656.       {
  657.          FreeItem(&globalMemList, table[i]);
  658.       }
  659.    }
  660.    DateStamp((void *)&ds2);
  661.  
  662.    ds2.ds_Tick -= ds1.ds_Tick;
  663.    ds2.ds_Minute -= ds1.ds_Minute;
  664.    if (ds2.ds_Tick < 0)
  665.    {
  666.       --ds2.ds_Minute;
  667.       ds2.ds_Tick += (60 * 50);
  668.    }
  669.    ds2.ds_Days = ds2.ds_Minute;
  670.    ds2.ds_Minute = ds2.ds_Tick / 50;
  671.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  672.  
  673.    VPrintf("SHADOW memory test completed.\n", NULL);
  674.    i = 50 * 64000;
  675.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  676.    VPrintf("\t%ld SHADOW memory allocs-frees/second\n\n", &i);
  677.  
  678.    /*
  679.     * A3000 tests after decent memory usage by other programs
  680.     * shows a bit over 12700 a second.
  681.     */
  682.  
  683.    VPrintf("Beginning Exec allocation speed test:\n", NULL);
  684.  
  685.    DateStamp((void *)&ds1);
  686.  
  687.    for(j = 0; j < 500; j++)
  688.    {
  689.       for (i = 0; i < 128; i++)
  690.       {
  691.          table[i] = AllocMem(16, MEMF_PUBLIC);
  692.       }
  693.       for (i = 0; i < 128; i++)
  694.       {
  695.          FreeMem(table[i], 16);
  696.       }
  697.    }
  698.    DateStamp((void *)&ds2);
  699.  
  700.    ds2.ds_Tick -= ds1.ds_Tick;
  701.    ds2.ds_Minute -= ds1.ds_Minute;
  702.    if (ds2.ds_Tick < 0)
  703.    {
  704.       --ds2.ds_Minute;
  705.       ds2.ds_Tick += (60 * 50);
  706.    }
  707.    ds2.ds_Days = ds2.ds_Minute;
  708.    ds2.ds_Minute = ds2.ds_Tick / 50;
  709.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  710.  
  711.    VPrintf("Exec memory test completed.\n", NULL);
  712.    i = 50 * 64000;
  713.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  714.    VPrintf("\t%ld system memory allocs-frees/second\n\n", &i);
  715.  
  716.    /*
  717.     * A3000 tests after decent memory usage by other programs
  718.     *  shows a bit under 8000 a second.
  719.     *
  720.     * The comparisons are even more disparate for slightly larger
  721.     *  memory block sizes.  After all, very few fragments need be
  722.     *  searched for blocks of 16bytes -- smallest frag. size is 8!
  723.     */
  724.    FreeTable(&globalMemList);
  725. }
  726.  
  727. void SemaphoreSpeedTest(void)
  728. {
  729.    int i, j;
  730.    ULONG table[12];
  731.    struct DateStamp ds1, ds2;
  732.  
  733.    VPrintf("Beginning SHADOW semaphore speed test:\n", NULL);
  734.  
  735.    for(i = 0; i < 12; i++)
  736.    {
  737.       table[i] = lrand48();
  738.    }
  739.  
  740.    DateStamp((void *)&ds1);
  741.  
  742.    for(j = 0; j < 1000; j++)
  743.    {
  744.       for (i = 0; i < 12; i++)
  745.       {
  746.          PSem((void *)table[i], SHADOW_EXCLUSIVE_SEMAPHORE);
  747.       }
  748.       for (i = 0; i < 12; i++)
  749.       {
  750.          VSem((void *)table[i]);
  751.       }
  752.    }
  753.    DateStamp((void *)&ds2);
  754.  
  755.    ds2.ds_Tick -= ds1.ds_Tick;
  756.    ds2.ds_Minute -= ds1.ds_Minute;
  757.    if (ds2.ds_Tick < 0)
  758.    {
  759.       --ds2.ds_Minute;
  760.       ds2.ds_Tick += (60 * 50);
  761.    }
  762.    ds2.ds_Days = ds2.ds_Minute;
  763.    ds2.ds_Minute = ds2.ds_Tick / 50;
  764.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  765.  
  766.    VPrintf("SHADOW semaphore test completed.\n", NULL);
  767.    i = 50 * 12000;
  768.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  769.    VPrintf("\t%ld SHADOW semaphore Psem()-VSem()/second\n\n", &i);
  770.  
  771.    /*
  772.     * A3000 tests shows a bit over 8500 a second.
  773.     */
  774. }
  775.  
  776. #define STRINGTESTER "Find this string in Table"
  777.  
  778. void StringSpeedTest(void)
  779. {
  780.    int i;
  781.    struct DateStamp ds1, ds2;
  782.  
  783.    VPrintf("Beginning SHADOW word-aligned FindString() speed test:\n", NULL);
  784.  
  785.    UseString(STRINGTESTER);
  786.  
  787.    DateStamp((void *)&ds1);
  788.  
  789.    for(i = 0; i < 50000; i++)
  790.    {
  791.       FindString(STRINGTESTER);
  792.    }
  793.    DateStamp((void *)&ds2);
  794.  
  795.    ds2.ds_Tick -= ds1.ds_Tick;
  796.    ds2.ds_Minute -= ds1.ds_Minute;
  797.    if (ds2.ds_Tick < 0)
  798.    {
  799.       --ds2.ds_Minute;
  800.       ds2.ds_Tick += (60 * 50);
  801.    }
  802.    ds2.ds_Days = ds2.ds_Minute;
  803.    ds2.ds_Minute = ds2.ds_Tick / 50;
  804.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  805.  
  806.    VPrintf("SHADOW FindString() test completed.\n", NULL);
  807.    i = 50 * 50000;
  808.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  809.    VPrintf("\t%ld SHADOW FindString()/second\n\n", &i);
  810.  
  811.    DropString(STRINGTESTER);
  812.  
  813.    /*
  814.     * A3000 tests shows a bit under 21000 a second.
  815.     */
  816.  
  817.    VPrintf("Beginning SHADOW unaligned FindString() speed test:\n", NULL);
  818.  
  819.    UseString(STRINGTESTER + 1);
  820.  
  821.    DateStamp((void *)&ds1);
  822.  
  823.    for(i = 0; i < 50000; i++)
  824.    {
  825.       FindString(STRINGTESTER + 1);
  826.    }
  827.    DateStamp((void *)&ds2);
  828.  
  829.    ds2.ds_Tick -= ds1.ds_Tick;
  830.    ds2.ds_Minute -= ds1.ds_Minute;
  831.    if (ds2.ds_Tick < 0)
  832.    {
  833.       --ds2.ds_Minute;
  834.       ds2.ds_Tick += (60 * 50);
  835.    }
  836.    ds2.ds_Days = ds2.ds_Minute;
  837.    ds2.ds_Minute = ds2.ds_Tick / 50;
  838.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  839.  
  840.    VPrintf("SHADOW FindString() test completed.\n", NULL);
  841.    i = 50 * 50000;
  842.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  843.    VPrintf("\t%ld SHADOW FindString()/second\n\n", &i);
  844.  
  845.    DropString(STRINGTESTER + 1);
  846.  
  847.    /*
  848.     * A3000 tests shows around 17000 a second -- 15%-20% slower!.
  849.     */
  850. }
  851.  
  852. /*
  853.  * The speed and testing test methods.
  854.  */
  855. double PreTestMethod(METHOD_ARGS)
  856. {
  857.    static myLocalVar = 0;
  858.    union {
  859.       double tempD;
  860.       ULONG  tempV[2];
  861.    } retval;
  862.  
  863.    VPrintf("Pretest called\n", NULL);
  864.  
  865.    if (!(retval.tempV[1] = (myLocalVar++ & 1)))
  866.       VPrintf("PreTest will block this call:\n", NULL);
  867.  
  868.    /*
  869.     * Try to fool it into returning 100.  It won't.
  870.     */
  871.    retval.tempV[0] = 100;
  872.    return retval.tempD;
  873. }
  874.  
  875. long PostTestMethod(METHOD_ARGS)
  876. {
  877.    VPrintf("Post test called\n", NULL);
  878.    return 200;
  879. }
  880.  
  881. METHOD_REF REF_TestMethod[] = {
  882.                                  {'JSTR', sizeof(char *), 0},
  883.                                  {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  884.                               };
  885.  
  886. long TestMethod(METHOD_ARGS, char *string)
  887. {
  888.    long args[10];
  889.  
  890.    if (!string)
  891.       string = "NULL";
  892.  
  893.    args[0] = (long)MethodID;
  894.    if (!msg)
  895.       args[1] = (ULONG)"SMET";
  896.    else
  897.       args[1] = (long)&msg->ipc_Id;
  898.    args[2] = (long)FindTask(NULL)->tc_Node.ln_Name;
  899.    VPrintf("Method <%s> called via <%s> Message recv'd by task <%s>.\n", args);
  900.  
  901.    args[0] = (long)class->meta_name;
  902.    args[1] = (long)object;
  903.    VPrintf("\tClass = '%s', OBJECT = '%lx'\n", args);
  904.  
  905.    args[0] = (long)string;
  906.    args[1] = *(long *)(((ULONG)&string) + 4);
  907.    VPrintf("\tArgument STRING sent <%s> :: %lx\n", args);
  908.  
  909.    return TRUE;
  910.  
  911. }
  912.  
  913. long Test5Method(METHOD_ARGS)
  914. {
  915.    return TRUE;
  916. }
  917.  
  918. METHOD_REF REF_SendTestMethod[] = {
  919.                                      {'JOBJ', sizeof(char *), SHADOW_OBJECT},
  920.                                      {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  921.                                   };
  922.  
  923. long SendTestMethod(METHOD_ARGS, OBJECT testObject)
  924. {
  925.    long test, args[3];
  926.  
  927.    args[0] = (long)MethodID;
  928.    if (!msg)
  929.       args[1] = (ULONG)"SMET";
  930.    else
  931.       args[1] = (long)&msg->ipc_Id;
  932.    args[2] = (long)FindTask(NULL)->tc_Node.ln_Name;
  933.    VPrintf("Method <%s> called via <%s> Message recv'd by task <%s>.\n", args);
  934.  
  935.    args[0] = (long)class->meta_name;
  936.    args[1] = (long)object;
  937.    VPrintf("\tClass = '%s', OBJECT = '%lx'\n", args);
  938.  
  939.    args[0] = (long)testObject;
  940.    VPrintf("\tArgument OBJECT sent <%lx>\n\n", args);
  941.  
  942.    test = (long)DoJazzMethod(testObject, NULL, MethodID,
  943.                                                    "Testing", METHOD_END);
  944.  
  945.    VPrintf("Method Call first Returned %ld\n\n", &test);
  946.  
  947.    test = (long)DoJazzMethod(testObject, NULL, MethodID, METHOD_END);
  948.  
  949.    VPrintf("Method Call second Returned %ld\n\n", &test);
  950.  
  951.    return TRUE;
  952.  
  953. }
  954.  
  955. METHOD_REF REF_SendTest5Method[] = {
  956.                                       {'JOBJ', sizeof(char *),SHADOW_OBJECT},
  957.                                       {TAG_DONE, SHADOW_RETURN_BLANK, 0}
  958.                                    };
  959.  
  960. long SendTest5Method(METHOD_ARGS, OBJECT testObject)
  961. {
  962.    int i;
  963.    struct DateStamp ds1, ds2;
  964. /*
  965.  * Use this for testing the DJM() call, which is a bit faster than
  966.  *  DoJazzMethod() [maybe 10% faster].
  967.  *
  968.  * void *args[4];
  969.  *
  970.  * args[0] = testObject;
  971.  * args[1] = testObject->cob_class;
  972.  * args[2] = METHOD_TEST_SPEED;
  973.  * args[3] = METHOD_END;
  974.  */
  975.  
  976.  
  977.    VPrintf("Beginning SHADOW method speed test:\n", NULL);
  978.  
  979.    Delay(30);  /* let things settle a bit */
  980.  
  981.    DateStamp((void *)&ds1);
  982.    for (i = 0; i< SPEEDTESTNUMBER; i++)
  983.    {
  984.       /*
  985.        * The following would be a little bit faster than the DoJazzMethod
  986.        *  call.
  987.        * DJM(args, SHADOW_MSG_FINDMETHOD);
  988.        */
  989.  
  990.       DoJazzMethod(testObject, NULL, METHOD_TEST_SPEED, METHOD_END);
  991.    }
  992.  
  993.    DateStamp((void *)&ds2);
  994.  
  995.    ds2.ds_Tick -= ds1.ds_Tick;
  996.    ds2.ds_Minute -= ds1.ds_Minute;
  997.    if (ds2.ds_Tick < 0)
  998.    {
  999.       --ds2.ds_Minute;
  1000.       ds2.ds_Tick += (60 * 50);
  1001.    }
  1002.    ds2.ds_Days = ds2.ds_Minute;
  1003.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1004.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1005.  
  1006.    VPrintf("SHADOW method test completed.\n", NULL);
  1007.    i = 50 * SPEEDTESTNUMBER;
  1008.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1009.    VPrintf("\t%ld methods/second\n\n", &i);
  1010.  
  1011.    /*
  1012.     * A3000 tests under moderate system usage (maky apps Open, nothing
  1013.     *  running) shows 30000+.
  1014.     */
  1015.  
  1016.    VPrintf("Beginning function call speed test:\n", NULL);
  1017.    DateStamp((void *)&ds1);
  1018.    for (i = 0; i< SPEEDTESTNUMBER; i++)
  1019.       Test5Method(NULL, testObject, testObject->cob_class, METHOD_TEST_SPEED);
  1020.  
  1021.    DateStamp((void *)&ds2);
  1022.  
  1023.    ds2.ds_Tick -= ds1.ds_Tick;
  1024.    ds2.ds_Minute -= ds1.ds_Minute;
  1025.    if (ds2.ds_Tick < 0)
  1026.    {
  1027.       --ds2.ds_Minute;
  1028.       ds2.ds_Tick += (60 * 50);
  1029.    }
  1030.    ds2.ds_Days = ds2.ds_Minute;
  1031.    ds2.ds_Minute = ds2.ds_Tick / 50;
  1032.    ds2.ds_Tick -= (ds2.ds_Minute * 50);
  1033.  
  1034.    VPrintf("Function call test completed.\n", NULL);
  1035.    i = 50 * SPEEDTESTNUMBER;
  1036.    i = i / ((ds2.ds_Days * 60 + ds2.ds_Minute) * 50 + ds2.ds_Tick);
  1037.    VPrintf("\t%ld functio calls/second\n\n", &i);
  1038.  
  1039.    /*
  1040.     * A3000 tests under moderate system usage (many apps Open, nothing
  1041.     *  running) shows 230000 for funcs/sec.
  1042.     */
  1043.  
  1044.    return TRUE;
  1045. }
  1046.  
  1047.